package com.yupi.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yupi.project.service.MailService;
import com.yupi.project.service.UserService;
import com.yupi.project.utils.PasswordUtil;
import com.yupi.yuapicommon.model.common.BusinessException;
import com.yupi.yuapicommon.model.common.ErrorCode;
import com.yupi.yuapicommon.model.dto.user.UserLoginRequest;
import com.yupi.yuapicommon.model.entity.User;
import com.yupi.yuapicommon.model.vo.UserVO;
import com.yupi.yuapicommon.model.vo.req.EmailMsgRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.yupi.yuapicommon.model.constant.UserConstant.SALT;
import static com.yupi.yuapicommon.model.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @description: 邮箱服务
 * @author SummerBird
 * @date 2024/2/19 11:15
 * @version 1.0
 */
@Service
@Slf4j
public class MailServiceImpl implements MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private UserService userService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //application.properties中已配置的值
    @Value("${spring.mail.username}")
    private String from;

    // 验证码过期时间5分钟
    public static final int CODE_EXPIRED_TIME = 5;

    private static final String CACHE_KEY = "imageCaptcha:";

    /**
     * 给前端输入的邮箱，发送验证码
     * @param email
     * @return
     */
    @Override
    public boolean sendMimeMail(String email) {
        try {
            SimpleMailMessage mailMessage = new SimpleMailMessage();

            mailMessage.setSubject("验证码邮件");//主题
            //生成随机数
            String code = randomCode();

            // 验证码有效期5分钟
            stringRedisTemplate.opsForValue().set(email,code, CODE_EXPIRED_TIME, TimeUnit.MINUTES);

            mailMessage.setText("您收到的验证码是："+code);//内容

            mailMessage.setTo(email);//发给谁

            mailMessage.setFrom(from);//你自己的邮箱

            mailSender.send(mailMessage);//发送
            return  true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }


    @Override
    public String sendMsg(EmailMsgRequest emailMsgRequest) {
        String newPassword = PasswordUtil.randomPassword(12);
        try {
            SimpleMailMessage mailMessage = new SimpleMailMessage();

            mailMessage.setSubject(emailMsgRequest.getTitle());//主题

            mailMessage.setText(String.format("您的新密码是：%s", newPassword));//内容

            mailMessage.setTo(emailMsgRequest.getToEmail());//发给谁

            mailMessage.setFrom(from);//你自己的邮箱

            mailSender.send(mailMessage);//发送
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return newPassword;
    }

    /**
     * 随机生成6位数的验证码
     * @return String code
     */
    public String randomCode(){
        StringBuilder str = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            str.append(random.nextInt(10));
        }
        return str.toString();
    }

    /**
     * 检验验证码是否一致
     * @return
     */
    @Override
    public User registered(UserLoginRequest userLoginRequest, HttpServletRequest request){

        //获取表单中的提交的验证信息
        String code = userLoginRequest.getCode();
        String userEmail = userLoginRequest.getUserEmail();

        //如果email数据为空，或者不一致，注册失败
        if (userEmail == null || userEmail.isEmpty()){
            log.error("邮箱为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱为空");
        } else if (StringUtils.isBlank(code)){
            log.error("验证码为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码为空");
        }
        String codeInRedis = stringRedisTemplate.opsForValue().get(userEmail);
        if (!code.equals(codeInRedis)){
            log.error("验证码错误");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误");
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserEmail, userEmail);
        // 登录成功，删除验证码缓存
        stringRedisTemplate.delete(userEmail);
        User user = userService.getOne(queryWrapper);
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        //跳转成功页面
        return user;
    }

    /**
     * 通过输入email查询password，然后比较两个password，如果一样，登录成功
     * @param email
     * @param password
     * @return
     */
    @Override
    public User loginIn(String email, String password, HttpServletRequest request){

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserEmail, email);
        User user = userService.getOne(queryWrapper);
        if(user == null){
            log.error("用户不存在");
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        }
        if(StringUtils.isBlank(password)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不能为空");
        }
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        if(!encryptPassword.equals(user.getUserPassword())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
        }
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        return user;
    }

    @Override
    public boolean verifyCode(String userEmail, String code, HttpServletRequest request) {
        //如果email数据为空，或者不一致，注册失败
        if (userEmail == null || userEmail.isEmpty()){
            log.error("邮箱为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱为空");
        } else if (StringUtils.isBlank(code)){
            log.error("验证码为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码为空");
        }
        String codeInRedis = stringRedisTemplate.opsForValue().get(userEmail);
        if (!code.equals(codeInRedis)){
            log.error("验证码错误");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误");
        }
        //String isVerifyCaptcha = stringRedisTemplate.opsForValue().get(CACHE_KEY + request.getSession().getId());
        //if(StringUtils.isBlank(isVerifyCaptcha) || !"success".equals(isVerifyCaptcha)){
        //    throw new BusinessException(ErrorCode.PARAMS_ERROR, "请先通过图片验证码！");
        //}
        // 登录成功，删除验证码缓存 和图片验证码
        stringRedisTemplate.delete(userEmail);
        stringRedisTemplate.delete(CACHE_KEY + request.getSession().getId());
        //跳转成功页面
        return true;
    }
}
